﻿// <copyright file="TaskServiceBase.cs" company="DotNetLib">
//
// .netlib: http://www.codeplex.com/DotNetLib
//
// This code is released under the New BSD License.
// A copy of this license is available at:
// http://www.codeplex.com/DotNetLib/license
//
// </copyright>

namespace DotNetLib.ServiceProcess
{
  using System;
  using System.ServiceProcess;
  using System.Timers;

  /// <summary>
  /// Base class for task oriented services that need to execute on an interval.
  /// </summary>
  public abstract class TaskServiceBase : ServiceBase
  {
    private Timer timer = new Timer();

    /// <summary>
    /// Initializes a new instance of <see cref="TaskServiceBase"/> class with the specified interval.
    /// </summary>
    /// <param name="interval">The frequency of the task.</param>
    /// <remarks>Service will wait the interval <b>after</b> the completion of a task before starting again.</remarks>
    protected TaskServiceBase(TimeSpan interval)
    {
      this.timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
      this.timer.Interval = interval.TotalMilliseconds;
      this.timer.AutoReset = false;
      this.timer.Enabled = false;
    }

    /// <summary>
    /// Specifies action to take when the service starts.
    /// </summary>
    /// <param name="args">Data passed by the start command.</param>
    protected override void OnStart(string[] args)
    {
      this.timer.Start();
    }

    /// <summary>
    /// Specifies action to take when the service stops.
    /// </summary>
    protected override void OnStop()
    {
      this.timer.Stop();
    }

    /// <summary>
    /// Implementation of the task to be executed on an interval.
    /// </summary>
    protected abstract void RunTask();

    private void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
      this.timer.Stop();

      try
      {
        this.RunTask();
      }
      finally
      {
        this.timer.Start();
      }
    }
  }
}
